package com.atguigu.pratice2;



import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//*  * 多线程之间按顺序调用，实现A->B->C
//        *  * 三个线程启动，要求如下：
//        *  *
//        *  * AA打印5次，BB打印10次，CC打印15次
//        *  * 接着
//        *  * AA打印5次，BB打印10次，CC打印15次
//        *  * ......来10轮
//  线程 操作  资源类
//  判断 干活  通知
//避免虚假唤醒
//通知判定标志位

class ShareData {
    //假设info=1为A，info=2为B，info=3为C,
    private int info = 1;
    //打印5次
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    public void print5() throws InterruptedException {
        lock.lock();
        //判断
        while (info != 1) {
            //等待
            condition1.await();
        }

        //干活
        try {
            for (int i = 1; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i);
            }
            //通知
            info = 2;
            condition2.signal();
        } finally {
            lock.unlock();
        }

    }

    //打印10次
    public void print10() throws InterruptedException {
        lock.lock();
        //判断
        while (info != 2) {
            condition2.await();
        }
        //干活
        try {
            for (int i = 1; i <= 10; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i);
            }
            //通知3
            info = 3;
            condition3.signal();
        } finally {
            lock.unlock();
        }


    }

    //打印15次
    public void print15() throws InterruptedException {
        lock.lock();
        //判断
        while (info != 3) {
            condition3.await();
        }
        try {
            for (int i = 1; i <= 15; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i);

                //通知1
                info = 1;
                condition1.signal();

            }
        } finally {
            lock.unlock();

        }
    }
}
    public class ThreadOrderAccess {
        public static void main(String[] args) {
            ShareData shareData = new ShareData();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.print5();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }, "A").start();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.print10();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }
            }, "B").start();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    try {
                        shareData.print15();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }, "C").start();
        }
    }
